"""
用户业务模型
包含:
1. UserPointRecordModel - 积分记录
2. UserBalanceRecordModel - 余额记录
3. UserSignInRecordModel - 签到记录
"""

from datetime import datetime, date, timedelta
from typing import Optional

from tortoise import fields

from app.core.constants import BalanceSourceType, PointSourceType
from app.models.base_model import BaseModel


class UserPointRecordModel(BaseModel):
    """用户积分记录"""

    user = fields.ForeignKeyField("models.UserModel", related_name="point_records", null=False, description="用户")
    amount = fields.IntField(description="变动积分数")
    before_points = fields.IntField(description="变动前积分")
    after_points = fields.IntField(description="变动后积分")
    source_type = fields.IntEnumField(PointSourceType, default=PointSourceType.OTHER, description="来源类型")
    remark = fields.CharField(max_length=255, null=True, description="备注")

    class Meta:
        table = "auth_user_point_record"


class UserBalanceRecordModel(BaseModel):
    """用户余额记录"""

    user = fields.ForeignKeyField("models.UserModel", related_name="balance_records", null=False, description="用户")
    amount = fields.DecimalField(max_digits=10, decimal_places=6, description="变动金额")
    before_balance = fields.DecimalField(max_digits=10, decimal_places=6, description="变动前余额")
    after_balance = fields.DecimalField(max_digits=10, decimal_places=6, description="变动后余额")
    source_type = fields.IntEnumField(BalanceSourceType, default=BalanceSourceType.OTHER, description="来源类型")
    remark = fields.CharField(max_length=255, null=True, description="备注")

    class Meta:
        table = "auth_user_balance_record"


class UserSignInRecordModel(BaseModel):
    """用户签到记录"""

    user = fields.ForeignKeyField("models.UserModel", related_name="sign_in_records", null=False, description="用户")
    points = fields.IntField(description="积分")
    ip = fields.CharField(max_length=255, description="IP地址")
    continuous_days = fields.IntField(default=1, description="连续签到天数")
    sign_in_date = fields.DateField(auto_now_add=True, description="签到日期")
    extra_points = fields.IntField(default=0, description="额外奖励积分")
    device = fields.CharField(max_length=255, null=True, description="签到设备")
    location = fields.CharField(max_length=255, null=True, description="签到地点")

    class Meta:
        table = "auth_user_sign_in_record"
        indexes = (("user_id", "sign_in_date"),)

    @classmethod
    async def get_user_today_record(cls, user_id: int) -> Optional["UserSignInRecordModel"]:
        """获取用户今日签到记录"""
        today = datetime.now().date()
        return await cls.filter(user_id=user_id, sign_in_date=today).first()

    @classmethod
    async def get_user_last_record(cls, user_id: int) -> Optional["UserSignInRecordModel"]:
        """获取用户最后一次签到记录"""
        return await cls.filter(user_id=user_id).order_by("-created_at").first()

    @classmethod
    async def calculate_continuous_days(cls, user_id: int, current_date: date) -> int:
        """计算连续签到天数"""
        last_record = await cls.get_user_last_record(user_id)
        if not last_record:
            return 1

        # 如果上次签到日期是昨天,连续签到天数+1
        if last_record.sign_in_date == current_date - timedelta(days=1):
            return last_record.continuous_days + 1

        # 如果是今天重复签到,保持不变
        if last_record.sign_in_date == current_date:
            return last_record.continuous_days

        # 否则重置为1
        return 1
